from airtest.core.api import *
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
from logger import logger, DEFAULT_PATH
from airtest import aircv
from element import Element
import os
import cv2


def log_poco(func):
    def inner(*args):
        obj = func(*args)
        logger.info("return poco = {}".format(obj))
        return obj

    return inner


class Driver:
    index = 0

    def __init__(self, config):
        logger.info("devices: {}".format(config.get("devices", "")))
        auto_setup(__file__, devices=config.get("devices", None))

        self.driver = device()
        self.poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
        self.path = DEFAULT_PATH

    def start_app(self, package):
        logger.info("start_app:{}".format(package))
        self.driver.start_app(package)

    def dump(self):
        dump = self.poco.agent.hierarchy.dump()
        logger.info("dump: {}".format(dump))
        return dump

    def get_activity(self):
        return self.driver.get_top_activity_name()

    def screenshot(self, filename):
        return self.driver.snapshot(filename=filename, quality=ST.SNAPSHOT_QUALITY)

    def _get_poco_from_value(self, value: dict):
        name = value.get("name", None)
        kw = {}

        if "type" in value:
            kw["type"] = value["type"]
        if "text" in value:
            kw["text"] = value["text"]

        logger.info("element:name:{},{}".format(name, kw))
        poco = self.poco(name, **kw)
        length = len(poco)
        if length > 1:
            local = value["zOrders"]["local"]
            logger.info("poco length > 1 ={} ,local {}".format(length, local))
            if local <= length:
                return poco[local - 1]
        return poco

    def _screenshot_before_and_after(self, poco, value, action, func):
        pos = poco.get_position()
        img_name_prefix = self._creat_file_name_prefix(value, action)

        logger.info("do {}:{}:{}".format(action, poco, value))
        logger.info("screenshot path name: {}".format(img_name_prefix))

        img = self._draw_point(self.screenshot(None), pos)
        aircv.imwrite(img_name_prefix + "1.png", img, ST.SNAPSHOT_QUALITY)
        func()
        self.screenshot(img_name_prefix + "2.png")

    @log_poco
    def get_poco_item(self, value):
        logger.info("find element {}".format(value))
        if isinstance(value, Element):
            poco = value.element(self.poco)
        else:
            poco = self._get_poco_from_value(value)
        return poco

    def send_key(self, value: dict, text):
        poco = self.get_poco_item(value)

        def temp():
            poco.set_text(text)

        self._screenshot_before_and_after(poco, value, "send_key", temp)

    def click(self, value):
        poco = self.get_poco_item(value)

        def temp():
            poco.click()

        self._screenshot_before_and_after(poco, value, "click", temp)

    def swipe(self, pos1, pos2):
        self.poco.swipe(pos1, pos2)

    def back(self):
        logger.info("KEY EVENT BACK")
        self.driver.keyevent("BACK")
        sleep(1)

    def _creat_file_name_prefix(self, value, action):
        self.index += 1
        logger.info("index {}".format(self.index))
        name = value.get("name", "")
        if "/" in name:
            _, name = name.split("/")
        prefix = "{}_{}_{}_{}".format(self.index, time.time(), name, action)
        return os.path.join(self.path, prefix)

    def _draw_point(self, img, pos):
        h, w, _ = img.shape
        _w, _h = pos
        p = (int(_w * w), int(h * _h))
        color = (0, 0, 255)
        cv2.circle(img, p, 5, color, -1)
        cv2.circle(img, p, 15, color, 3)

        return img
